package wechat

import (
	"context"
	"encoding/json"
	// "fmt"
	"net/http"

	"mall/common/mqueuex"
	"mall/common/resultx"
	"mall/service/pay/api/internal/svc"
	"mall/service/pay/api/internal/types"
	// "mall/service/pay/rpc/payclient"

	"github.com/pkg/errors"
	// "github.com/sirupsen/logrus"
	"github.com/wechatpay-apiv3/wechatpay-go/core/auth/verifiers"
	"github.com/wechatpay-apiv3/wechatpay-go/core/downloader"
	"github.com/wechatpay-apiv3/wechatpay-go/core/notify"
	"github.com/wechatpay-apiv3/wechatpay-go/services/refunddomestic"
	"github.com/zeromicro/go-zero/core/logx"
)

var WechatRefundCallbackError = resultx.NewErrCode(resultx.PAYMENT_WECHAT_REFUND_CALLBACK_FAIL)

type WechatRefundCallbackLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewWechatRefundCallbackLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WechatRefundCallbackLogic {
	return &WechatRefundCallbackLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *WechatRefundCallbackLogic) WechatRefundCallback(req *http.Request) (resp *types.CallbackResponse, err error) {
	// Retrieve the local merchant certificate private key.
	_, err = svc.NewWxPayClientV3(l.svcCtx.Config)
	if err != nil {
		return nil, err
	}

	// Get platform certificate accessor
	certVisitor := downloader.MgrInstance().GetCertificateVisitor(l.svcCtx.Config.WxPayConf.MchId)
	handler := notify.NewNotifyHandler(l.svcCtx.Config.WxPayConf.APIv3Key, verifiers.NewSHA256WithRSAVerifier(certVisitor))
	// Verifying signatures, parsing data
	refund := new(refunddomestic.Refund)
	_, err = handler.ParseNotifyRequest(context.Background(), req, refund)
	if err != nil {
		return nil, errors.Wrapf(WechatRefundCallbackError, "Failed to parse data, err: %v", err)
	}

	returnCode := "SUCCESS"
	// notify  sub "payment-update-tradestate-topic"  services(backend-rmq ..), pub、sub use kq
	if err = l.pubKqPaymentRefund(refund); err != nil {
		// logx.WithContext(l.ctx).Errorf("WechatRefundCallback pubKqPaymentRefund, err: %+v ", err)
		logx.Errorw("WechatRefundCallback pubKqPaymentRefund error", logx.Field("detail", err.Error()))
		returnCode = "FAIL"
	}

	return &types.CallbackResponse{
		ReturnCode: returnCode,
	}, err
}

func (l *WechatRefundCallbackLogic) pubKqPaymentRefund(notifyRefund *refunddomestic.Refund) error {
	// logrus.Info(fmt.Sprintf("WechatRefundCallback pubKqPaymentRefund notifyRefund: %+v", *notifyRefund))
	// logx.Infof("WechatRefundCallback pubKqPaymentRefund notifyRefund: %+v ", *notifyRefund)
	// Refund{
	// 	RefundId:50303901222024101051445756517,
	// 	OutRefundNo:RF20241010184154843810001,
	// 	TransactionId:4200002376202410106989334989,
	// 	OutTradeNo:PMT20241010184014518810001,
	// 	Channel:\u003cnil\u003e,
	// 	UserReceivedAccount:支付用户零钱,
	// 	SuccessTime:2024-10-10 18:42:08 +0800 CST,
	// 	CreateTime:\u003cnil\u003e,
	// 	Status:\u003cnil\u003e,
	// 	FundsAccount:\u003cnil\u003e,
	// 	Amount:Amount{
	// 		Total:2,
	// 		Refund:2,
	// 		From:[],
	// 		PayerTotal:2,
	// 		PayerRefund:2,
	// 		SettlementRefund:\u003cnil\u003e,
	// 		SettlementTotal:\u003cnil\u003e,
	// 		DiscountRefund:\u003cnil\u003e,
	// 		Currency:\u003cnil\u003e
	// 	},
	// 	PromotionDetail:[]
	// }
	m := mqueuex.ThirdPartPaymentRefundMessage{
		RefundId:      notifyRefund.RefundId,
		OutRefundNo:   notifyRefund.OutRefundNo,
		TransactionId: notifyRefund.TransactionId,
		OutTradeNo:    notifyRefund.OutTradeNo,
		Total:         notifyRefund.Amount.Total,
		Refund:        notifyRefund.Amount.Refund,
		PayerTotal:    notifyRefund.Amount.PayerTotal,
		PayerRefund:   notifyRefund.Amount.PayerRefund,
	}
	body, err := json.Marshal(m)
	if err != nil {
		logx.Errorw("kq WechatRefundCallback pushKqPaymentRefund json.Marshal error", logx.Field("detail", err.Error()))
		return errors.Wrapf(
			resultx.NewErrCodeMsg(resultx.PAYMENT_WECHAT_PAY_CALLBACK_FAIL, "kq WechatRefundCallback pubKqPaymentRefund json.Marshal error"),
			"kq WechatRefundCallback pushKqPaymentRefund json.Marshal error, v: %+v",
			m,
		)
	}

	return l.svcCtx.KqPaymentRefundClient.Push(string(body))
}

// Verify and update relevant flow data
// func (l *WechatRefundCallbackLogic) verifyAndUpdateTradeState(notifyRefund *refunddomestic.Refund) error {
// 	logrus.Info(fmt.Sprintf("WechatRefundCallbackLogic verifyAndUpdateTradeState notifyRefund: %+v", *notifyRefund))

// 	paymentResp, err := l.svcCtx.PayRpc.GetPaymentBySn(l.ctx, &payclient.GetPaymentBySnRequest{
// 		Sn: *notifyRefund.OutTradeNo,
// 	})
// 	if err != nil || paymentResp.PaymentDetail.Id == 0 {
// 		return errors.Wrapf(WechatRefundCallbackError, "Failed to get payment flow record err: %v , notifyRefund: %+v ", err, notifyRefund)
// 	}

// 	// 比对金额
// 	notifyPayTotal := *notifyRefund.Amount.PayerTotal
// 	if paymentResp.PaymentDetail.PayTotal != notifyPayTotal {
// 		return errors.Wrapf(WechatRefundCallbackError, "Order amount exception notifyPayTotal: %v , notifyRefund: %v ", notifyPayTotal, notifyTrasaction)
// 	}

// 	// Judgment status
// 	payStatus := l.parseTradeStateFromWeChatPayToThirdPartyPayment(*notifyRefund.TradeState)
// 	if payStatus == mqueuex.ThirdPartyPaymentTradeStateSuccess {
// 		// Payment Notification.
// 		if paymentResp.PaymentDetail.PayStatus != mqueuex.ThirdPartyPaymentTradeStateNotPay {
// 			return nil
// 		}

// 		// Update the flow status.
// 		if _, err = l.svcCtx.PayRpc.UpdateTradeState(l.ctx, &payclient.UpdateTradeStateRequest{
// 			Sn:             *notifyRefund.OutTradeNo,
// 			TradeState:     *notifyRefund.TradeState,
// 			TransactionId:  *notifyRefund.TransactionId,
// 			TradeType:      *notifyRefund.TradeType,
// 			TradeStateDesc: *notifyRefund.TradeStateDesc,
// 			PayStatus:      payStatus,
// 		}); err != nil {
// 			return errors.Wrapf(WechatRefundCallbackError, "更新流水状态失败  err: %v , notifyRefund: %v ", err, notifyRefund)
// 		}

// 	} else if payStatus == mqueuex.ThirdPartyPaymentTradeStateNotPay {
// 		// Refund notification @todo to be done later, not needed at this time
// 	}

// 	return nil
// }

// func (l *WechatRefundCallbackLogic) parseTradeStateFromWeChatPayToThirdPartyPayment(weChatPayTradeState string) int32 {
// 	switch weChatPayTradeState {
// 	case mqueuex.WeChatPayTradeStateSuccess: // 支付成功
// 		return mqueuex.ThirdPartyPaymentTradeStateSuccess
// 	case mqueuex.WeChatPayTradeStateUserPaying: // 支付中
// 		return mqueuex.ThirdPartyPaymentTradeStateUserPaying
// 	case mqueuex.WeChatPayTradeStateRefund: // 已退款
// 		return mqueuex.ThirdPartyPaymentTradeStateRefund
// 	default:
// 		return mqueuex.ThirdPartyPaymentTradeStatePayError
// 	}
// }
